home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / cagd_lib / cagd_aux.c < prev    next >
C/C++ Source or Header  |  1995-12-30  |  54KB  |  1,179 lines

  1. /******************************************************************************
  2. * Cagd_aux.c - auxiliary routine to interface to different free from types.   *
  3. *******************************************************************************
  4. * Written by Gershon Elber, July. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. #define VEC_FIELD_TRIES    10
  10. #define VEC_FIELD_START_STEP 1e-6
  11.  
  12.  
  13. /*****************************************************************************
  14. * DESCRIPTION:                                                               M
  15. *   Returns the parametric domain of a curve.                              M
  16. *                                                                            *
  17. * PARAMETERS:                                                                M
  18. *   Crv:       To get its parametric domain.                                 M
  19. *   TMin:      Where to put the minimal domain's boundary.                   M
  20. *   TMax:      Where to put the maximal domain's boundary.                   M
  21. *                                                                            *
  22. * RETURN VALUE:                                                              M
  23. *   void                                                                     M
  24. *                                                                            *
  25. * KEYWORDS:                                                                  M
  26. *   CagdCrvDomain, domain, parametric domain                                 M
  27. *****************************************************************************/
  28. void CagdCrvDomain(CagdCrvStruct *Crv, CagdRType *TMin, CagdRType *TMax)
  29. {
  30.     switch (Crv -> GType) {
  31.     case CAGD_CBEZIER_TYPE:
  32.         *TMin = 0.0;
  33.         *TMax = 1.0;
  34.         break;
  35.     case CAGD_CBSPLINE_TYPE:
  36.         BspCrvDomain(Crv, TMin, TMax);
  37.         break;
  38.     case CAGD_CPOWER_TYPE:
  39.     default:
  40.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  41.         break;
  42.     }
  43. }
  44.  
  45. /*****************************************************************************
  46. * DESCRIPTION:                                                               M
  47. * Given a curve and parameter value t, evaluate the curve at t.             M
  48. *                                                                            *
  49. * PARAMETERS:                                                                M
  50. *   Crv:      To evaluate at the given parametric location t.                M
  51. *   t:        The parameter value at which the curve Crv is to be evaluated. M
  52. *                                                                            *
  53. * RETURN VALUE:                                                              M
  54. *   CagdRType *:  A vector holding all the coefficients of all components    M
  55. *                 of curve Crv's point type. If for example the curve's      M
  56. *                 point type is P2, the W, X, and Y will be saved in the     M
  57. *                 first three locations of the returned vector. The first    M
  58. *                 location (index 0) of the returned vector is reserved for  M
  59. *                 the rational coefficient W and XYZ always starts at second M
  60. *                 location of the returned vector (index 1).                 M
  61. *                                                                            *
  62. * KEYWORDS:                                                                  M
  63. *   CagdCrvEval, evaluation                                                  M
  64. *****************************************************************************/
  65. CagdRType *CagdCrvEval(CagdCrvStruct *Crv, CagdRType t)
  66. {
  67.     switch (Crv -> GType) {
  68.     case CAGD_CBEZIER_TYPE:
  69.         return BzrCrvEvalAtParam(Crv, t);
  70.     case CAGD_CBSPLINE_TYPE:
  71.         return BspCrvEvalAtParam(Crv, t);
  72.     case CAGD_CPOWER_TYPE:
  73.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  74.         return NULL;
  75.     default:
  76.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  77.         return NULL;
  78.     }
  79. }
  80.  
  81. /*****************************************************************************
  82. * DESCRIPTION:                                                               M
  83. *   Returns the parametric domain of a surface.                     M
  84. *                                                                            *
  85. * PARAMETERS:                                                                M
  86. *   Srf:       To get its parametric domain.                                 M
  87. *   UMin:      Where to put the minimal U domain's boundary.                 M
  88. *   UMax:      Where to put the maximal U domain's boundary.                 M
  89. *   VMin:      Where to put the minimal V domain's boundary.                 M
  90. *   VMax:      Where to put the maximal V domain's boundary.                 M
  91. *                                                                            *
  92. * RETURN VALUE:                                                              M
  93. *   void                                                                     M
  94. *                                                                            *
  95. * KEYWORDS:                                                                  M
  96. *   CagdSrfDomain, domain, parametric domain                                 M
  97. *****************************************************************************/
  98. void CagdSrfDomain(CagdSrfStruct *Srf,
  99.            CagdRType *UMin,
  100.            CagdRType *UMax,
  101.            CagdRType *VMin,
  102.            CagdRType *VMax)
  103. {
  104.     switch (Srf -> GType) {
  105.     case CAGD_SBEZIER_TYPE:
  106.         *UMin = 0.0;
  107.         *UMax = 1.0;
  108.         *VMin = 0.0;
  109.         *VMax = 1.0;
  110.         break;
  111.     case CAGD_SBSPLINE_TYPE:
  112.         BspSrfDomain(Srf, UMin, UMax, VMin, VMax);
  113.         break;
  114.     case CAGD_SPOWER_TYPE:
  115.     default:
  116.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  117.         break;
  118.     }
  119. }
  120.  
  121. /*****************************************************************************
  122. * DESCRIPTION:                                                               M
  123. * Given a surface and parameter values u, v, evaluate the surface at (u, v). M
  124. *                                                                            *
  125. * PARAMETERS:                                                                M
  126. *   Srf:     To evaluate at the given parametric location (u, v).            M
  127. *   u, v:    The parameter values at which the curve Crv is to be evaluated. M
  128. *                                                                            *
  129. * RETURN VALUE:                                                              M
  130. *   CagdRType *:  A vector holding all the coefficients of all components    M
  131. *                 of surface Srf's point type. If for example the surface's  M
  132. *                 point type is P2, the W, X, and Y will be saved in the     M
  133. *                 first three locations of the returned vector. The first    M
  134. *                 location (index 0) of the returned vector is reserved for  M
  135. *                 the rational coefficient W and XYZ always starts at second M
  136. *                 location of the returned vector (index 1).                 M
  137. *                                                                            *
  138. * KEYWORDS:                                                                  M
  139. *   CagdSrfEval, evaluation                                                  M
  140. *****************************************************************************/
  141. CagdRType *CagdSrfEval(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  142. {
  143.     switch (Srf -> GType) {
  144.     case CAGD_SBEZIER_TYPE:
  145.         return BzrSrfEvalAtParam(Srf, u, v);
  146.     case CAGD_SBSPLINE_TYPE:
  147.         return BspSrfEvalAtParam(Srf, u, v);
  148.     case CAGD_SPOWER_TYPE:
  149.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  150.         return NULL;
  151.     default:
  152.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  153.         return NULL;
  154.     }
  155. }
  156.  
  157. /*****************************************************************************
  158. * DESCRIPTION:                                                               M
  159. * Evaluates a vector field surface to a unit size vector. If fails, moves a  M
  160. * tad until success. Useful for normal field evaluations.             M
  161. *                                                                            *
  162. * PARAMETERS:                                                                M
  163. *   Vec:            Where resulting unit length vector is to be saved.       M
  164. *   VecFieldSrf:    A surface representing a vector field.                   M
  165. *   U, V:           Parameter locations.                                     M
  166. *                                                                            *
  167. * RETURN VALUE:                                                              M
  168. *   void                                                                     M
  169. *                                                                            *
  170. * KEYWORDS:                                                                  M
  171. *   CagdEvaluateSurfaceVecField, normal, vector field                        M
  172. *****************************************************************************/
  173. void CagdEvaluateSurfaceVecField(CagdVType Vec,
  174.                  CagdSrfStruct *VecFieldSrf,
  175.                  CagdRType U,
  176.                  CagdRType V)
  177. {
  178.     CagdRType
  179.     *R = CagdSrfEval(VecFieldSrf, U, V);
  180.  
  181.     CagdCoerceToE3(Vec, &R, -1, VecFieldSrf -> PType);
  182.  
  183.     if (PT_LENGTH(Vec) < IRIT_EPSILON) {
  184.     int i = 0;
  185.     CagdRType UMin, UMax, VMin, VMax, UMid, VMid,
  186.         Step = VEC_FIELD_START_STEP;
  187.  
  188.     CagdSrfDomain(VecFieldSrf, &UMin, &UMax, &VMin, &VMax);
  189.     UMid = (UMin + UMax) / 2;
  190.     VMid = (VMin + VMax) / 2;
  191.     while (PT_LENGTH(Vec) < IRIT_EPSILON && i++ < VEC_FIELD_TRIES) {
  192.         U += U < UMid ? Step : -Step;
  193.         V += V < VMid ? Step : -Step;
  194.         Step *= 2.0;
  195.  
  196.         R = CagdSrfEval(VecFieldSrf, U, V);
  197.         CagdCoerceToE3(Vec, &R, -1, VecFieldSrf -> PType);
  198.     }
  199.     if (i >= VEC_FIELD_TRIES)
  200.         CAGD_FATAL_ERROR(CAGD_ERR_CANNOT_COMP_VEC_FIELD);
  201.     }
  202.  
  203.     PT_NORMALIZE(Vec);
  204. }
  205.  
  206. /*****************************************************************************
  207. * DESCRIPTION:                                                               M
  208. * Given a curve, computes its derivative curve (Hodograph).                  M
  209. *                                                                            *
  210. * PARAMETERS:                                                                M
  211. *   Crv:      To compute its Hodograph curve.                                M
  212. *                                                                            *
  213. * RETURN VALUE:                                                              M
  214. *   CagdCrvStruct *:  Resulting hodograph.                                   M
  215. *                                                                            *
  216. * KEYWORDS:                                                                  M
  217. *   CagdCrvDerive, derivatives, Hodograph                                    M
  218. *****************************************************************************/
  219. CagdCrvStruct *CagdCrvDerive(CagdCrvStruct *Crv)
  220. {
  221.     switch (Crv -> GType) {
  222.     case CAGD_CBEZIER_TYPE:
  223.         return BzrCrvDerive(Crv);
  224.     case CAGD_CBSPLINE_TYPE:
  225.         return BspCrvDerive(Crv);
  226.     case CAGD_CPOWER_TYPE:
  227.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  228.         return NULL;
  229.     default:
  230.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  231.         return NULL;
  232.     }
  233. }
  234.  
  235. /*****************************************************************************
  236. * DESCRIPTION:                                                               M
  237. * Given a curve, compute its integral curve.                                 M
  238. *                                                                            *
  239. * PARAMETERS:                                                                M
  240. *   Crv:      To compute its integral curve.                                 M
  241. *                                                                            *
  242. * RETURN VALUE:                                                              M
  243. *   CagdCrvStruct *:  Resulting integral curve.                              M
  244. *                                                                            *
  245. * KEYWORDS:                                                                  M
  246. *   CagdCrvIntegrate, integrals                                              M
  247. *****************************************************************************/
  248. CagdCrvStruct *CagdCrvIntegrate(CagdCrvStruct *Crv)
  249. {
  250.     switch (Crv -> GType) {
  251.     case CAGD_CBEZIER_TYPE:
  252.         return BzrCrvIntegrate(Crv);
  253.     case CAGD_CBSPLINE_TYPE:
  254.         return BspCrvIntegrate(Crv);
  255.     case CAGD_CPOWER_TYPE:
  256.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  257.         return NULL;
  258.     default:
  259.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  260.         return NULL;
  261.     }
  262. }
  263.  
  264. /*****************************************************************************
  265. * DESCRIPTION:                                                               M
  266. * Given a surface, computes its partial derivative in the prescibed          M
  267. * direction Dir.                                 M
  268. *                                                                            *
  269. * PARAMETERS:                                                                M
  270. *   Srf:      To compute its derivative surface in direction Dir.            M
  271. *   Dir:      Direction of differentiation. Either U or V.                   M
  272. *                                                                            *
  273. * RETURN VALUE:                                                              M
  274. *   CagdSrfStruct *:  Resulting partial derivative surface.                  M
  275. *                                                                            *
  276. * KEYWORDS:                                                                  M
  277. *   CagdSrfDerive, derivatives, partial derivatives                          M
  278. *****************************************************************************/
  279. CagdSrfStruct *CagdSrfDerive(CagdSrfStruct *Srf, CagdSrfDirType Dir)
  280. {
  281.     switch (Srf -> GType) {
  282.     case CAGD_SBEZIER_TYPE:
  283.         return BzrSrfDerive(Srf, Dir);
  284.     case CAGD_SBSPLINE_TYPE:
  285.         return BspSrfDerive(Srf, Dir);
  286.     case CAGD_SPOWER_TYPE:
  287.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  288.         return NULL;
  289.     default:
  290.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  291.         return NULL;
  292.     }
  293. }
  294.  
  295. /*****************************************************************************
  296. * DESCRIPTION:                                                               M
  297. * Given a curve - subdivides it into two curves at the given parameter       M
  298. * value t.                                     M
  299. *    Returns pointer to first curve in a list of two subdivided curves.      M
  300. *                                                                            *
  301. * PARAMETERS:                                                                M
  302. *   Crv:      To subdivide at the prescibed parameter value t.               M
  303. *   t:        The parameter to subdivide the curve Crv at.                   M
  304. *                                                                            *
  305. * RETURN VALUE:                                                              M
  306. *   CagdCrvStruct *:  A list of the two curves resulting from the process    M
  307. *                     of subdivision.                                        M
  308. *                                                                            *
  309. * KEYWORDS:                                                                  M
  310. *   CagdCrvSubdivAtParam, subdivision                                        M
  311. *****************************************************************************/
  312. CagdCrvStruct *CagdCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t)
  313. {
  314.     switch (Crv -> GType) {
  315.     case CAGD_CBEZIER_TYPE:
  316.         return BzrCrvSubdivAtParam(Crv, t);
  317.     case CAGD_CBSPLINE_TYPE:
  318.         return BspCrvSubdivAtParam(Crv, t);
  319.     case CAGD_CPOWER_TYPE:
  320.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  321.         return NULL;
  322.     default:
  323.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  324.         return NULL;
  325.     }
  326. }
  327.  
  328. /*****************************************************************************
  329. * DESCRIPTION:                                                               M
  330. * Given a curve - extracts a sub-region within the domain specified by t1    M
  331. * and t2.                                                                    M
  332. *                                                                            *
  333. * PARAMETERS:                                                                M
  334. *   Crv:       To extract a sub-region from.                                 M
  335. *   t1, t2:    Parametric domain boundaries of sub-region.                   M
  336. *                                                                            *
  337. * RETURN VALUE:                                                              M
  338. *   CagdCrvStruct *:  Sub-region extracted from Crv from t1 to t2.           M
  339. *                                                                            *
  340. * KEYWORDS:                                                                  M
  341. *   CagdCrvRegionFromCrv, regions, subdivision                               M
  342. *****************************************************************************/
  343. CagdCrvStruct *CagdCrvRegionFromCrv(CagdCrvStruct *Crv,
  344.                     CagdRType t1,
  345.                     CagdRType t2)
  346. {
  347.     CagdRType TMin, TMax;
  348.     CagdCrvStruct *Crvs;
  349.     CagdBType
  350.     BezCrv = FALSE,
  351.     OpenEnd = TRUE,
  352.     NewCrv = FALSE;
  353.  
  354.     switch (Crv -> GType) {
  355.     case CAGD_CBEZIER_TYPE:
  356.         BezCrv = TRUE;
  357.         break;
  358.     case CAGD_CBSPLINE_TYPE:
  359.         OpenEnd = BspCrvHasOpenEC(Crv);
  360.         break;
  361.     case CAGD_CPOWER_TYPE:
  362.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  363.         return NULL;
  364.     default:
  365.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  366.         return NULL;
  367.     }
  368.  
  369.     CagdCrvDomain(Crv, &TMin, &TMax);
  370.     CAGD_DOMAIN_T_VERIFY(t1, TMin, TMax);
  371.     CAGD_DOMAIN_T_VERIFY(t2, TMin, TMax);
  372.  
  373.     if (t1 > t2)
  374.     SWAP(CagdRType, t1, t2);
  375.  
  376.     if (!APX_EQ(t1, TMin) || !OpenEnd) {
  377.         Crvs = CagdCrvSubdivAtParam(Crv, t1);
  378.     Crv = Crvs -> Pnext;
  379.     Crvs -> Pnext = NULL;
  380.     CagdCrvFree(Crvs);               /* Free the first region. */
  381.     NewCrv = TRUE;
  382.     }
  383.  
  384.     if (APX_EQ(t2, TMax) && OpenEnd)
  385.     return NewCrv ? Crv : CagdCrvCopy(Crv);
  386.     else {
  387.     if (BezCrv)
  388.         t2 = (t2 - t1) / (TMax - t1);
  389.  
  390.     Crvs = CagdCrvSubdivAtParam(Crv, t2);
  391.  
  392.     if (NewCrv)
  393.         CagdCrvFree(Crv);
  394.  
  395.         CagdCrvFree(Crvs -> Pnext);          /* Free the second region. */
  396.         Crvs -> Pnext = NULL;
  397.         return Crvs;                /* Returns the first region. */
  398.     }
  399. }
  400.  
  401. /*****************************************************************************
  402. * DESCRIPTION:                                                               M
  403. * Given a curve - refines it at the given n knots as defined by vector t.    M
  404. * If Replace is TRUE, the values in t replaces current knot vector.         M
  405. * Returns pointer to refined surface (Note a Bezier curve will be converted  M
  406. * into a Bspline curve).                                                     M
  407. *                                                                            *
  408. * PARAMETERS:                                                                M
  409. *   Crv:       To refine.                                                    M
  410. *   Replace:   If TRUE, t holds knots in exactly the same length as the      M
  411. *              length of the knot vector of Crv and t simply replaces the    M
  412. *              knot vector.                                                  M
  413. *   t:         Vector of knots with length of n.                             M
  414. *   n:         Length of vector t.                                           M
  415. *                                                                            *
  416. * RETURN VALUE:                                                              M
  417. *   CagdCrvStruct *:  A refined curve of Crv after insertion of all the      M
  418. *                     knots as specified by vector t of length n.            M
  419. *                                                                            *
  420. * KEYWORDS:                                                                  M
  421. *   CagdCrvRefineAtParams, refinement, subdivision                           M
  422. *****************************************************************************/
  423. CagdCrvStruct *CagdCrvRefineAtParams(CagdCrvStruct *Crv,
  424.                      CagdBType Replace,
  425.                      CagdRType *t,
  426.                      int n)
  427. {
  428.     CagdCrvStruct *BspCrv, *TCrv;
  429.  
  430.     switch (Crv -> GType) {
  431.     case CAGD_CBEZIER_TYPE:
  432.             BspCrv = CnvrtBezier2BsplineCrv(Crv);
  433.         TCrv = BspCrvKnotInsertNDiff(BspCrv, Replace, t, n);
  434.         CagdCrvFree(BspCrv);
  435.         return TCrv;
  436.     case CAGD_CBSPLINE_TYPE:
  437.         return BspCrvKnotInsertNDiff(Crv, Replace, t, n);
  438.     case CAGD_CPOWER_TYPE:
  439.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  440.         return NULL;
  441.     default:
  442.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  443.         return NULL;
  444.     }
  445. }
  446.  
  447. /*****************************************************************************
  448. * DESCRIPTION:                                                               M
  449. * Returns a new curve that is the reversed curve of Crv by reversing the     M
  450. * control polygon and the knot vector of Crv is a Bspline curve.             M
  451. * See also BspKnotReverse.                                                   M
  452. *                                                                            *
  453. * PARAMETERS:                                                                M
  454. *   Crv:       To be reversed.                                               M
  455. *                                                                            *
  456. * RETURN VALUE:                                                              M
  457. *   CagdCrvStruct *:   Reversed curve of Crv.                                M
  458. *                                                                            *
  459. * KEYWORDS:                                                                  M
  460. *   CagdCrvReverse, reverse                                                  M
  461. *****************************************************************************/
  462. CagdCrvStruct *CagdCrvReverse(CagdCrvStruct *Crv)
  463. {
  464.     CagdBType
  465.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  466.     int i, Len, Col,
  467.     Length = Crv -> Length,
  468.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  469.     CagdCrvStruct
  470.         *ReversedCrv = CagdCrvCopy(Crv);
  471.     CagdRType *KV,
  472.     **Points = ReversedCrv -> Points;
  473.  
  474.     switch (Crv -> GType) {
  475.     case CAGD_CBEZIER_TYPE:
  476.     case CAGD_CBSPLINE_TYPE:
  477.         break;
  478.     case CAGD_CPOWER_TYPE:
  479.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  480.         return NULL;
  481.     default:
  482.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  483.         return NULL;
  484.     }
  485.  
  486.     /* Reverse the Ctl Polygon: */
  487.     Len = Length / 2;
  488.     for (Col = 0; Col < Len; Col++)
  489.     for (i = IsNotRational; i <= MaxCoord; i++)
  490.         SWAP(CagdRType,
  491.          Points[i][Col],
  492.          Points[i][Length - Col - 1]);
  493.  
  494.     /* Reverse the knot vector if it exists: */
  495.     if (Crv -> GType == CAGD_CBSPLINE_TYPE &&
  496.     Crv -> KnotVector != NULL) {
  497.     KV = BspKnotReverse(Crv -> KnotVector, Crv -> Order + Length);
  498.     IritFree((VoidPtr) ReversedCrv -> KnotVector);
  499.     ReversedCrv -> KnotVector = KV;
  500.     }
  501.  
  502.     return ReversedCrv;
  503. }
  504.  
  505. /*****************************************************************************
  506. * DESCRIPTION:                                                               M
  507. * Returns a new curve representing the same curve as Crv but with its degree M
  508. * raised by one.                                 M
  509. *                                                                            *
  510. * PARAMETERS:                                                                M
  511. *   Crv:       To raise its degree.                                          M
  512. *                                                                            *
  513. * RETURN VALUE:                                                              M
  514. *   CagdCrvStruct *:  A curve with same geometry as Crv but with one degree  M
  515. *                     higher.                                                M
  516. *                                                                            *
  517. * KEYWORDS:                                                                  M
  518. *   CagdCrvDegreeRaise, degree raising                                       M
  519. *****************************************************************************/
  520. CagdCrvStruct *CagdCrvDegreeRaise(CagdCrvStruct *Crv)
  521. {
  522.     switch (Crv -> GType) {
  523.     case CAGD_CBEZIER_TYPE:
  524.         return BzrCrvDegreeRaise(Crv);
  525.     case CAGD_CBSPLINE_TYPE:
  526.         return BspCrvDegreeRaise(Crv);
  527.     case CAGD_CPOWER_TYPE:
  528.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  529.         return NULL;
  530.     default:
  531.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  532.         return NULL;
  533.     }
  534. }
  535.  
  536. /*****************************************************************************
  537. * DESCRIPTION:                                                               M
  538. * Returns a new curve representing the same curve as Crv but with its degree M
  539. * raised to NewOrder                                 M
  540. *                                                                            *
  541. * PARAMETERS:                                                                M
  542. *   Crv:        To raise its degree.                                         M
  543. *   NewOrder:   Expected new order of the raised curve.                      M
  544. *                                                                            *
  545. * RETURN VALUE:                                                              M
  546. *   CagdCrvStruct *:  A curve with same geometry as Crv but with order that  M
  547. *                     is equal to NewOrder.                                  M
  548. *                                                                            *
  549. * KEYWORDS:                                                                  M
  550. *   CagdCrvDegreeRaiseN, degree raising                                      M
  551. *****************************************************************************/
  552. CagdCrvStruct *CagdCrvDegreeRaiseN(CagdCrvStruct *Crv, int NewOrder)
  553. {
  554.     switch (Crv -> GType) {
  555.     case CAGD_CBEZIER_TYPE:
  556.         return BzrCrvDegreeRaiseN(Crv, NewOrder);
  557.     case CAGD_CBSPLINE_TYPE:
  558.         return BspCrvDegreeRaiseN(Crv, NewOrder);
  559.     case CAGD_CPOWER_TYPE:
  560.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  561.         return NULL;
  562.     default:
  563.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  564.         return NULL;
  565.     }
  566. }
  567.  
  568. /*****************************************************************************
  569. * DESCRIPTION:                                                               M
  570. * Returns a new surface representing the same surface as Srf but with its    M
  571. * degree raised by one.                                 M
  572. *                                                                            *
  573. * PARAMETERS:                                                                M
  574. *   Srf:       To raise its degree.                                          M
  575. *   Dir:       Direction of degree raising. Either U or V.             M
  576. *                                                                            *
  577. * RETURN VALUE:                                                              M
  578. *   CagdSrfStruct *:  A surface with same geometry as Srf but with one       M
  579. *                     degree higher.                                         M
  580. *                                                                            *
  581. * KEYWORDS:                                                                  M
  582. *   CagdSrfDegreeRaise, degree raising                                       M
  583. *****************************************************************************/
  584. CagdSrfStruct *CagdSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir)
  585. {
  586.     switch (Srf -> GType) {
  587.     case CAGD_SBEZIER_TYPE:
  588.         return BzrSrfDegreeRaise(Srf, Dir);
  589.     case CAGD_SBSPLINE_TYPE:
  590.         return BspSrfDegreeRaise(Srf, Dir);
  591.     case CAGD_SPOWER_TYPE:
  592.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  593.         return NULL;
  594.     default:
  595.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  596.         return NULL;
  597.     }
  598. }
  599.  
  600. /*****************************************************************************
  601. * DESCRIPTION:                                                               M
  602. * Extracts an isoparametric curve from the surface Srf in direction Dir at   M
  603. * the parameter value of t.                                                  M
  604. *                                                                            *
  605. * PARAMETERS:                                                                M
  606. *   Srf:       To extract an isoparametric curve from.                       M
  607. *   t:         Parameter value of extracted isoparametric curve.             M
  608. *   Dir:       Direction of extracted isoparametric curve. Either U or V.    M
  609. *                                                                            *
  610. * RETURN VALUE:                                                              M
  611. *   CagdCrvStruct *:   An isoparametric curve of Srf. This curve inherit the M
  612. *                      order and continuity of surface Srf in direction Dir. M
  613. *                                                                            *
  614. * KEYWORDS:                                                                  M
  615. *   CagdCrvFromSrf, isoparametric curves, curve from surface                 M
  616. *****************************************************************************/
  617. CagdCrvStruct *CagdCrvFromSrf(CagdSrfStruct *Srf,
  618.                   CagdRType t,
  619.                   CagdSrfDirType Dir)
  620. {
  621.     switch (Srf -> GType) {
  622.     case CAGD_SBEZIER_TYPE:
  623.         return BzrSrfCrvFromSrf(Srf, t, Dir);
  624.     case CAGD_SBSPLINE_TYPE:
  625.         return BspSrfCrvFromSrf(Srf, t, Dir);
  626.     case CAGD_SPOWER_TYPE:
  627.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  628.         return NULL;
  629.     default:
  630.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  631.         return NULL;
  632.     }
  633. }
  634.  
  635. /*****************************************************************************
  636. * DESCRIPTION:                                                               M
  637. * Extracts a curve from the mesh of surface Srf in direction Dir at index    M
  638. * Index.                                                                     M
  639. *                                                                            *
  640. * PARAMETERS:                                                                M
  641. *   Srf:       To extract a curve from.                               M
  642. *   Index:     Index along the mesh of Srf to extract the curve from.        M
  643. *   Dir:       Direction of extracted curve. Either U or V.             M
  644. *                                                                            *
  645. * RETURN VALUE:                                                              M
  646. *   CagdCrvStruct *:   A curve from Srf. This curve inherit the  order and   M
  647. *                      continuity of surface Srf in direction Dir. However,  M
  648. *                      thiscurve is not on surface Srf, in general.          M
  649. *                                                                            *
  650. * KEYWORDS:                                                                  M
  651. *   CagdCrvFromMesh, isoparametric curves, curve from mesh                   M
  652. *****************************************************************************/
  653. CagdCrvStruct *CagdCrvFromMesh(CagdSrfStruct *Srf,
  654.                    int Index,
  655.                    CagdSrfDirType Dir)
  656. {
  657.     switch (Srf -> GType) {
  658.     case CAGD_SBEZIER_TYPE:
  659.         return BzrSrfCrvFromMesh(Srf, Index, Dir);
  660.     case CAGD_SBSPLINE_TYPE:
  661.         return BspSrfCrvFromMesh(Srf, Index, Dir);
  662.     case CAGD_SPOWER_TYPE:
  663.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  664.         return NULL;
  665.     default:
  666.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  667.         return NULL;
  668.     }
  669. }
  670.  
  671. /*****************************************************************************
  672. * DESCRIPTION:                                                               M
  673. * Substitutes a row/column of surface Srf from the given curve Crv at        M
  674. * surface direction Dir and mesh index Index. Curve must have the same       M
  675. * PtType/Length as the surface in the selected direction.             M
  676. *                                                                            *
  677. * PARAMETERS:                                                                M
  678. *   Crv:       To substitute into the surface Srf.                           M
  679. *   Index:     Of mesh where the curve Crv should be substituted in.         M
  680. *   Dir:       Either U or V.                                                M
  681. *   Srf:       That a row or a column of should be replaced by Crv.          M
  682. *                                                                            *
  683. * RETURN VALUE:                                                              M
  684. *   void                                                                     M
  685. *                                                                            *
  686. * KEYWORDS:                                                                  M
  687. *   CagdCrvToMesh, curve from mesh                                           M
  688. *****************************************************************************/
  689. void CagdCrvToMesh(CagdCrvStruct *Crv,
  690.            int Index,
  691.            CagdSrfDirType Dir,
  692.            CagdSrfStruct *Srf)
  693. {
  694.     CagdBType
  695.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  696.     int i, j,
  697.     Length = Crv -> Length,
  698.     ULength = Srf -> ULength,
  699.     VLength = Srf -> VLength,
  700.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  701.     CagdRType *CrvP, *SrfP;
  702.  
  703.     if (Crv -> PType != Srf -> PType ||
  704.     Length != (Dir == CAGD_CONST_U_DIR ? VLength : ULength))
  705.     CAGD_FATAL_ERROR(CAGD_ERR_PT_OR_LEN_MISMATCH);
  706.  
  707.     switch (Dir) {
  708.     case CAGD_CONST_U_DIR:
  709.         if (Index + 1 > ULength)
  710.         CAGD_FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  711.  
  712.         for (i = IsNotRational; i <= MaxCoord; i++) {
  713.         CrvP = Crv -> Points[i];
  714.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_U(Srf);
  715.         for (j = 0; j < Length; j++) {
  716.             *SrfP = *CrvP++;
  717.             SrfP += CAGD_NEXT_V(Srf);
  718.         }
  719.         }
  720.         break;
  721.     case CAGD_CONST_V_DIR:
  722.         if (Index + 1 > VLength)
  723.         CAGD_FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  724.  
  725.         for (i = IsNotRational; i <= MaxCoord; i++) {
  726.         CrvP = Crv -> Points[i];
  727.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_V(Srf);
  728.         for (j = 0; j < Length; j++) {
  729.             *SrfP = *CrvP++;
  730.             SrfP += CAGD_NEXT_U(Srf);
  731.         }
  732.         }
  733.         break;
  734.     default:
  735.         CAGD_FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  736.         break;
  737.     }
  738. }
  739.  
  740. /*****************************************************************************
  741. * DESCRIPTION:                                                               M
  742. * Given a surface - subdivides it into two sub-surfaces at given parametric  M
  743. * value t in the given direction Dir.                                        M
  744. *   Returns pointer to first surface in a list of two subdivided surfaces.   M
  745. *                                                                            *
  746. * PARAMETERS:                                                                M
  747. *   Srf:      To subdivide at the prescibed parameter value t.               M
  748. *   t:        The parameter to subdivide the curve Crv at.                   M
  749. *   Dir:      Direction of subdivision. Either U or V.                       M
  750. *                                                                            *
  751. * RETURN VALUE:                                                              M
  752. *   CagdSrfStruct *:  A list of the two surfaces resulting from the process  M
  753. *                     of subdivision.                                        M
  754. *                                                                            *
  755. * KEYWORDS:                                                                  M
  756. *   CagdSrfSubdivAtParam, subdivision                                        M
  757. *****************************************************************************/
  758. CagdSrfStruct *CagdSrfSubdivAtParam(CagdSrfStruct *Srf,
  759.                     CagdRType t,
  760.                     CagdSrfDirType Dir)
  761. {
  762.     switch (Srf -> GType) {
  763.     case CAGD_SBEZIER_TYPE:
  764.         return BzrSrfSubdivAtParam(Srf, t, Dir);
  765.     case CAGD_SBSPLINE_TYPE:
  766.         return BspSrfSubdivAtParam(Srf, t, Dir);
  767.     case CAGD_SPOWER_TYPE:
  768.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  769.         return NULL;
  770.     default:
  771.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  772.         return NULL;
  773.     }
  774. }
  775. /*****************************************************************************
  776. * DESCRIPTION:                                                               M
  777. * Given a surface - extracts a sub-region within the domain specified by t1  M
  778. * and t2, in the direction Dir.                                              M
  779. *                                                                            *
  780. * PARAMETERS:                                                                M
  781. *   Srf:       To extract a sub-region from.                                 M
  782. *   t1, t2:    Parametric domain boundaries of sub-region.                   M
  783. *   Dir:       Direction of region extraction. Either U or V.                M
  784. *                                                                            *
  785. * RETURN VALUE:                                                              M
  786. *   CagdSrfStruct *:  Sub-region extracted from Srf from t1 to t2.           M
  787. *                                                                            *
  788. * KEYWORDS:                                                                  M
  789. *   CagdSrfRegionFromSrf, regions, subdivision                               M
  790. *****************************************************************************/
  791. CagdSrfStruct *CagdSrfRegionFromSrf(CagdSrfStruct *Srf,
  792.                     CagdRType t1,
  793.                     CagdRType t2,
  794.                     CagdSrfDirType Dir)
  795. {
  796.     CagdRType TMin, TMax, R1, R2;
  797.     CagdSrfStruct *Srfs;
  798.     CagdBType
  799.     OpenEnd = FALSE,
  800.     NewSrf = FALSE;
  801.  
  802.     switch (Srf -> GType) {
  803.     case CAGD_SBEZIER_TYPE:
  804.         break;
  805.     case CAGD_SBSPLINE_TYPE:
  806.         OpenEnd = BspSrfHasOpenECDir(Srf, Dir);
  807.         break;
  808.     case CAGD_SPOWER_TYPE:
  809.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  810.         return NULL;
  811.     default:
  812.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  813.         return NULL;
  814.     }
  815.  
  816.     if (Dir == CAGD_CONST_U_DIR)
  817.     CagdSrfDomain(Srf, &TMin, &TMax, &R1, &R2);
  818.     else
  819.     CagdSrfDomain(Srf, &R1, &R2, &TMin, &TMax);
  820.     CAGD_DOMAIN_T_VERIFY(t1, TMin, TMax);
  821.     CAGD_DOMAIN_T_VERIFY(t2, TMin, TMax);
  822.  
  823.     if (t1 > t2)
  824.     SWAP(CagdRType, t1, t2);
  825.  
  826.     if (!APX_EQ(t1, TMin) || !OpenEnd) {
  827.     Srfs = CagdSrfSubdivAtParam(Srf, t1, Dir);
  828.     Srf = Srfs -> Pnext;
  829.     Srfs -> Pnext = NULL;
  830.     CagdSrfFree(Srfs);               /* Free the first region. */
  831.     NewSrf = TRUE;
  832.     }
  833.  
  834.     if (APX_EQ(t2, TMax) && OpenEnd)
  835.     return NewSrf ? Srf : CagdSrfCopy(Srf);
  836.     else {
  837.     Srfs = CagdSrfSubdivAtParam(Srf, t2, Dir);
  838.  
  839.     if (NewSrf)
  840.         CagdSrfFree(Srf);
  841.  
  842.         CagdSrfFree(Srfs -> Pnext);          /* Free the second region. */
  843.         Srfs -> Pnext = NULL;
  844.     return Srfs;                /* Returns the first region. */
  845.     }
  846. }
  847. /*****************************************************************************
  848. * DESCRIPTION:                                                               M
  849. * Given a surface - refines it at the given n knots as defined by vector t.  M
  850. *   If Replace is TRUE, the values in t replaces current knot vector.         M
  851. *   Returns pointer to refined surface (Note a Bezier surface will be        M
  852. * converted into a Bspline surface).                                         M
  853. *                                                                            *
  854. * PARAMETERS:                                                                M
  855. *   Srf:       To refine.                                                    M
  856. *   Dir:       Direction of refinement. Either U or V.                       M
  857. *   Replace:   If TRUE, t holds knots in exactly the same length as the      M
  858. *              length of the knot vector of Srf and t simply replaces the    M
  859. *              knot vector.                                                  M
  860. *   t:         Vector of knots with length of n.                             M
  861. *   n:         Length of vector t.                                           M
  862. *                                                                            *
  863. * RETURN VALUE:                                                              M
  864. *   CagdSrfStruct *:  A refined curve of Srf after insertion of all the      M
  865. *                     knots as specified by vector t of length n.            M
  866. *                                                                            *
  867. * KEYWORDS:                                                                  M
  868. *   CagdSrfRefineAtParams, refinement, subdivision                           M
  869. *****************************************************************************/
  870. CagdSrfStruct *CagdSrfRefineAtParams(CagdSrfStruct *Srf,
  871.                      CagdSrfDirType Dir,
  872.                      CagdBType Replace,
  873.                      CagdRType *t,
  874.                      int n)
  875. {
  876.     CagdSrfStruct *BspSrf, *TSrf;
  877.  
  878.     switch (Srf -> GType) {
  879.     case CAGD_SBEZIER_TYPE:
  880.             BspSrf = CnvrtBezier2BsplineSrf(Srf);
  881.         TSrf = BspSrfKnotInsertNDiff(BspSrf, Dir, Replace, t, n);
  882.         CagdSrfFree(BspSrf);
  883.         return TSrf;
  884.     case CAGD_SBSPLINE_TYPE:
  885.         return BspSrfKnotInsertNDiff(Srf, Dir, Replace, t, n);
  886.     case CAGD_SPOWER_TYPE:
  887.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  888.         return NULL;
  889.     default:
  890.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  891.         return NULL;
  892.     }
  893. }
  894.  
  895. /*****************************************************************************
  896. * DESCRIPTION:                                                               M
  897. * Given a curve Crv and a parameter value t, returns the unit tangent        M
  898. * direction of Crv at t.                                                     M
  899. *                                                                            *
  900. * PARAMETERS:                                                                M
  901. *   Crv:       To compute unit tangent vector for.                           M
  902. *   t:         Location where to evaluate the tangent of Crv.                M
  903. *                                                                            *
  904. * RETURN VALUE:                                                              M
  905. *   CagdVecStruct *:  A pointer to a static vector holding the unit tanegnt  M
  906. *                     information.                                           M
  907. *                                                                            *
  908. * KEYWORDS:                                                                  M
  909. *   CagdCrvTangent, tangent                                                  M
  910. *****************************************************************************/
  911. CagdVecStruct *CagdCrvTangent(CagdCrvStruct *Crv, CagdRType t)
  912. {
  913.     switch (Crv -> GType) {
  914.     case CAGD_CBEZIER_TYPE:
  915.         return BzrCrvTangent(Crv, t);
  916.     case CAGD_CBSPLINE_TYPE:
  917.         return BspCrvTangent(Crv, t);
  918.     case CAGD_CPOWER_TYPE:
  919.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  920.         return NULL;
  921.     default:
  922.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  923.         return NULL;
  924.     }
  925. }
  926.  
  927. /*****************************************************************************
  928. * DESCRIPTION:                                                               M
  929. * Given a curve Crv and a parameter value t, returns the unit binormal       M
  930. * direction of Crv at t.                                                     M
  931. *                                                                            *
  932. * PARAMETERS:                                                                M
  933. *   Crv:       To compute unit binormal vector for.                          M
  934. *   t:         Location where to evaluate the binormal of Crv.               M
  935. *                                                                            *
  936. * RETURN VALUE:                                                              M
  937. *   CagdVecStruct *:  A pointer to a static vector holding the unit binormal M
  938. *                     information.                                           M
  939. *                                                                            *
  940. * KEYWORDS:                                                                  M
  941. *   CagdCrvBiNormal, binormal                                                M
  942. *****************************************************************************/
  943. CagdVecStruct *CagdCrvBiNormal(CagdCrvStruct *Crv, CagdRType t)
  944. {
  945.     switch (Crv -> GType) {
  946.     case CAGD_CBEZIER_TYPE:
  947.         return BzrCrvBiNormal(Crv, t);
  948.     case CAGD_CBSPLINE_TYPE:
  949.         return BspCrvBiNormal(Crv, t);
  950.     case CAGD_CPOWER_TYPE:
  951.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  952.         return NULL;
  953.     default:
  954.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  955.         return NULL;
  956.     }
  957. }
  958.  
  959. /*****************************************************************************
  960. * DESCRIPTION:                                                               M
  961. * Given a curve Crv and a parameter value t, returns the unit normal         M
  962. * direction of Crv at t.                                                     M
  963. *                                                                            *
  964. * PARAMETERS:                                                                M
  965. *   Crv:       To compute unit normal vector for.                            M
  966. *   t:         Location where to evaluate the normal of Crv.                 M
  967. *                                                                            *
  968. * RETURN VALUE:                                                              M
  969. *   CagdVecStruct *:  A pointer to a static vector holding the unit normal   M
  970. *                     information.                                           M
  971. *                                                                            *
  972. * KEYWORDS:                                                                  M
  973. *   CagdCrvNormal, normal                                                    M
  974. *****************************************************************************/
  975. CagdVecStruct *CagdCrvNormal(CagdCrvStruct *Crv, CagdRType t)
  976. {
  977.     switch (Crv -> GType) {
  978.     case CAGD_CBEZIER_TYPE:
  979.         return BzrCrvNormal(Crv, t);
  980.     case CAGD_CBSPLINE_TYPE:
  981.         return BspCrvNormal(Crv, t);
  982.     case CAGD_CPOWER_TYPE:
  983.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  984.         return NULL;
  985.     default:
  986.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  987.         return NULL;
  988.     }
  989. }
  990.  
  991. /*****************************************************************************
  992. * DESCRIPTION:                                                               M
  993. * Given a surface Srf and a parameter values u, v, returns the unit tangent  M
  994. * vector of Srf in direction Dir.                                            M
  995. *                                                                            *
  996. * PARAMETERS:                                                                M
  997. *   Srf:       To compute unit tangent vector for.                           M
  998. *   u, v:      Location where to evaluate the tangent of Srf.                M
  999. *   Dir:       Direction of tangent, Either U or V.                 *
  1000. *                                                                            *
  1001. * RETURN VALUE:                                                              M
  1002. *   CagdVecStruct *:  A pointer to a static vector holding the unit tangent  M
  1003. *                     information.                                           M
  1004. *                                                                            *
  1005. * KEYWORDS:                                                                  M
  1006. *   CagdSrfTangent, tangent                                                  M
  1007. *****************************************************************************/
  1008. CagdVecStruct *CagdSrfTangent(CagdSrfStruct *Srf,
  1009.                   CagdRType u,
  1010.                   CagdRType v,
  1011.                   CagdSrfDirType Dir)
  1012. {
  1013.     switch (Srf -> GType) {
  1014.     case CAGD_SBEZIER_TYPE:
  1015.         return BzrSrfTangent(Srf, u, v, Dir);
  1016.     case CAGD_SBSPLINE_TYPE:
  1017.         return BspSrfTangent(Srf, u, v, Dir);
  1018.     case CAGD_SPOWER_TYPE:
  1019.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  1020.         return NULL;
  1021.     default:
  1022.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  1023.         return NULL;
  1024.     }
  1025. }
  1026.  
  1027. /*****************************************************************************
  1028. * DESCRIPTION:                                                               M
  1029. * Given a surface Srf and a parameter values u, v, returns the unit normal   M
  1030. * vector of Srf.                                                             M
  1031. *                                                                            *
  1032. * PARAMETERS:                                                                M
  1033. *   Srf:       To compute unit normal vector for.                            M
  1034. *   u, v:      Location where to evaluate the normal of Srf.                 M
  1035. *                                                                            *
  1036. * RETURN VALUE:                                                              M
  1037. *   CagdVecStruct *:  A pointer to a static vector holding the unit normal   M
  1038. *                     information.                                           M
  1039. *                                                                            *
  1040. * KEYWORDS:                                                                  M
  1041. *   CagdSrfNormal, normal                                                    M
  1042. *****************************************************************************/
  1043. CagdVecStruct *CagdSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  1044. {
  1045.     switch (Srf -> GType) {
  1046.     case CAGD_SBEZIER_TYPE:
  1047.         return BzrSrfNormal(Srf, u, v);
  1048.     case CAGD_SBSPLINE_TYPE:
  1049.         return BspSrfNormal(Srf, u, v);
  1050.     case CAGD_SPOWER_TYPE:
  1051.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  1052.         return NULL;
  1053.     default:
  1054.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  1055.         return NULL;
  1056.     }
  1057. }
  1058.  
  1059. /*****************************************************************************
  1060. * DESCRIPTION:                                                               M
  1061. * Returns a new surface that is the reversed surface of Srf by reversing the M
  1062. * control mesh and the knot vector (if Bspline surface) of Srf in the U      M
  1063. * direction. See also BspKnotReverse.                                        M
  1064. *                                                                            *
  1065. * PARAMETERS:                                                                M
  1066. *   Srf:       To be reversed.                                               M
  1067. *                                                                            *
  1068. * RETURN VALUE:                                                              M
  1069. *   CagdSrfStruct *:   Reversed surface of Srf.                              M
  1070. *                                                                            *
  1071. * KEYWORDS:                                                                  M
  1072. *   CagdSrfReverse, reverse                                                  M
  1073. *****************************************************************************/
  1074. CagdSrfStruct *CagdSrfReverse(CagdSrfStruct *Srf)
  1075. {
  1076.     CagdBType
  1077.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  1078.     int i, Len, Row, Col,
  1079.     ULength = Srf -> ULength,
  1080.     VLength = Srf -> VLength,
  1081.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  1082.     CagdSrfStruct
  1083.     *ReversedSrf = CagdSrfCopy(Srf);
  1084.     CagdRType *KV,
  1085.     **Points = ReversedSrf -> Points;
  1086.  
  1087.     switch (Srf -> GType) {
  1088.     case CAGD_SBEZIER_TYPE:
  1089.     case CAGD_SBSPLINE_TYPE:
  1090.         break;
  1091.     case CAGD_SPOWER_TYPE:
  1092.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  1093.         return NULL;
  1094.     default:
  1095.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  1096.         return NULL;
  1097.     }
  1098.  
  1099.     /* Reverse the Mesh: */
  1100.     Len = ULength / 2;
  1101.     for (Row = 0; Row < VLength; Row++)
  1102.     for (Col = 0; Col < Len; Col++)
  1103.         for (i = IsNotRational; i <= MaxCoord; i++)
  1104.         SWAP(CagdRType,
  1105.              Points[i][Row * ULength + Col],
  1106.              Points[i][Row * ULength + ULength - Col - 1]);
  1107.  
  1108.     /* Reverse the U knot vector if it exists: */
  1109.     if (Srf -> GType == CAGD_SBSPLINE_TYPE &&
  1110.     Srf -> UKnotVector != NULL) {
  1111.     KV = BspKnotReverse(Srf -> UKnotVector, Srf -> UOrder + ULength);
  1112.     IritFree((VoidPtr) ReversedSrf -> UKnotVector);
  1113.     ReversedSrf -> UKnotVector = KV;
  1114.     }
  1115.  
  1116.     return ReversedSrf;
  1117. }
  1118.  
  1119. /*****************************************************************************
  1120. * DESCRIPTION:                                                               M
  1121. * Returns a new surface that is the reversed surface of Srf by flipping the  M
  1122. * U and the V directions of the surface.                     M
  1123. * See also BspKnotReverse.                                             M
  1124. *                                                                            *
  1125. * PARAMETERS:                                                                M
  1126. *   Srf:       To be reversed.                                               M
  1127. *                                                                            *
  1128. * RETURN VALUE:                                                              M
  1129. *   CagdSrfStruct *:   Reversed surface of Srf.                              M
  1130. *                                                                            *
  1131. * KEYWORDS:                                                                  M
  1132. *   CagdSrfReverse, reverse                                                  M
  1133. *****************************************************************************/
  1134. CagdSrfStruct *CagdSrfReverse2(CagdSrfStruct *Srf)
  1135. {
  1136.     CagdBType
  1137.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  1138.     int i, Row, Col,
  1139.     ULength = Srf -> ULength,
  1140.     VLength = Srf -> VLength,
  1141.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  1142.     CagdSrfStruct
  1143.     *ReversedSrf = CagdSrfCopy(Srf);
  1144.     CagdRType
  1145.     **Points = Srf -> Points,
  1146.     **RevPoints = ReversedSrf -> Points;
  1147.  
  1148.     switch (Srf -> GType) {
  1149.     case CAGD_SBEZIER_TYPE:
  1150.     case CAGD_SBSPLINE_TYPE:
  1151.         break;
  1152.     case CAGD_SPOWER_TYPE:
  1153.         CAGD_FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  1154.         return NULL;
  1155.     default:
  1156.         CAGD_FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  1157.         return NULL;
  1158.     }
  1159.  
  1160.     /* Reverse the Mesh: */
  1161.     for (Row = 0; Row < VLength; Row++)
  1162.     for (Col = 0; Col < ULength; Col++)
  1163.         for (i = IsNotRational; i <= MaxCoord; i++)
  1164.         RevPoints[i][Col * VLength + Row] =
  1165.             Points[i][Row * ULength + Col];
  1166.  
  1167.     /* Swap the U and the V knot vectors if the exists: */
  1168.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  1169.     SWAP(CagdRType *,
  1170.          ReversedSrf -> UKnotVector, ReversedSrf -> VKnotVector);
  1171.     }
  1172.  
  1173.     /* And swap the orders and lengths. */
  1174.     SWAP(int, ReversedSrf -> UOrder, ReversedSrf -> VOrder);
  1175.     SWAP(int, ReversedSrf -> ULength, ReversedSrf -> VLength);
  1176.  
  1177.     return ReversedSrf;
  1178. }
  1179.